package com.weiaibenpao.demo.chislim.ui.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.weiaibenpao.demo.chislim.R;

/**
 * Created by wlx on 2017/11/29.
 */

public class DashBoardView extends View {
    private RectF rectF;
    private Paint arcPaint;
    private float bgArcWidth;//圆弧的宽度
    private int mSparkleWidth; // 亮点宽度
    private int mStartAngle; // 起始角度
    private int mSweepAngle ; // 绘制角度
    private Paint cirClePaint;
    private int bgArcColor ;//整个圆弧的颜色
    private int currColor;//当前圆弧的颜色
    private Paint tvPaint;
    private float textSize ;
    private int mPadding;//距离左右上下边距
    private int mRadius; // 画布边缘半径（去除padding后的半径）
    private float mLength1; // 刻度顶部相对边缘的长度
    private float mCenterX, mCenterY; // 圆心坐标
    private Rect mRectText;
    private double mMaxValue;//最大值
    private double mCurrValue;//当前值

    private boolean isAnimFinish = true;//动画是否结束
    private ValueAnimator progressAnimator;
    private double lastValue;
    private Paint currCirPaint;
    private float degree;//每次旋转的角度
    private PaintFlagsDrawFilter mDrawFilter;

    public DashBoardView(Context context) {
        this(context, null);
    }

    public DashBoardView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public DashBoardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initConfig(context, attrs);
        init();
    }

    private void init() {
        lastValue=mCurrValue;
        //矩形区域
        rectF = new RectF();
        mRectText = new Rect();
        //圆弧画笔
        arcPaint = new Paint();
        arcPaint.setAntiAlias(true);
        arcPaint.setStyle(Paint.Style.STROKE);
        arcPaint.setStrokeWidth(bgArcWidth);
        arcPaint.setColor(bgArcColor);
        //默认圆点的画笔
        cirClePaint = new Paint();
        cirClePaint.setAntiAlias(true);
        cirClePaint.setStyle(Paint.Style.FILL);
        cirClePaint.setColor(bgArcColor);
        cirClePaint.setStrokeWidth(dp2px(4));
        cirClePaint.setStrokeCap(Paint.Cap.ROUND);
        //当前进度的圆点
       currCirPaint = new Paint();
        currCirPaint.setAntiAlias(true);
        currCirPaint.setStyle(Paint.Style.FILL);
        currCirPaint.setColor(currColor);
        currCirPaint.setStrokeWidth(dp2px(4));
        currCirPaint.setStrokeCap(Paint.Cap.ROUND);
        //文字画笔 最粗的文字
        tvPaint = new Paint();
        tvPaint.setTextSize(textSize);
        tvPaint.setTextAlign(Paint.Align.CENTER);
        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mPadding = Math.max(
                Math.max(getPaddingLeft(), getPaddingTop()),
                Math.max(getPaddingRight(), getPaddingBottom())
        );
        setPadding(mPadding, mPadding, mPadding, mPadding);

        mLength1 = mPadding + mSparkleWidth / 2f + dp2px(8);

        int width = resolveSize(dp2px(250), widthMeasureSpec);
        mRadius = (width - mPadding ) / 2;

        setMeasuredDimension(width, width - dp2px(35));

        mCenterX = mCenterY = getMeasuredWidth() / 2f;
        /**
         * 圆弧属性设置
         */
        rectF.set(
                mPadding + mSparkleWidth /2f,
                mPadding + mSparkleWidth / 2f,
                getMeasuredWidth() - mPadding - mSparkleWidth / 2f,
                getMeasuredWidth() - mPadding - mSparkleWidth / 2f
        );
//        tvPaint.getTextBounds("0", 0, "0".length(), mRectText);
    }

    private void initConfig(Context context, AttributeSet attrs) {
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.DashBoardView);
        bgArcWidth = t.getInt(R.styleable.DashBoardView_bgArcWidth, dp2px(3));
        bgArcColor = t.getColor(R.styleable.DashBoardView_bgArcColor, Color.parseColor("#DFDFDF"));
        mSparkleWidth = t.getInt(R.styleable.DashBoardView_mSparkleWidth,dp2px(10));
        mStartAngle = t.getInt(R.styleable.DashBoardView_mStartAngle,135);
        mSweepAngle = t.getInt(R.styleable.DashBoardView_mSweepAngle,270);
        currColor = t.getInt(R.styleable.DashBoardView_currColor, Color.parseColor("#FF8044"));
        textSize = t.getInt(R.styleable.DashBoardView_textSize,sp2px(7));
        mCurrValue = t.getFloat(R.styleable.DashBoardView_mCurrValue,0);
        mMaxValue = t.getFloat(R.styleable.DashBoardView_mMaxValue,1000f);
        degree = t.getFloat(R.styleable.DashBoardView_degree,4.5f);

        t.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //抗锯齿
        canvas.setDrawFilter(mDrawFilter);

        /**
         * 画圆弧背景
         */
        arcPaint.setColor(bgArcColor);
        arcPaint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(rectF, mStartAngle, mSweepAngle, false, arcPaint);


        /**
         * 画当前进度的背景
         */
        if (mCurrValue>0){
            drawRunRect(canvas);
        }
        canvas.save();

        /**
         * 画刻度
         */
        drawRunDegree(canvas);
        canvas.restore();
        canvas.save();
        /**
         * 画文字
         */
        drawTvPaint(canvas);

    }

    private void drawTvPaint(Canvas canvas) {
        tvPaint.setColor(Color.parseColor("#333333"));

        /**
         * 固定的单位
         */
        tvPaint.setTextSize(sp2px(15));
        canvas.drawText("公里",mCenterX,mCenterY,tvPaint);
        /**
         * 当前里程
         */
//        tvPaint.setTextSize(sp2px(35));
//        canvas.drawText(String.format("%.2f", lastValue) + "", mCenterX, mCenterY - dp2px(27), tvPaint);
        /**
         * 总里程
         */
        tvPaint.setTextSize(sp2px(16));
        tvPaint.setColor(Color.parseColor("#666666"));
        canvas.drawText("总共" + String.format("%.2f", mMaxValue) + "公里", mCenterX, mCenterY + dp2px(40), tvPaint);

    }

    private void drawRunDegree(Canvas canvas) {
        double arcAngle = Math.toRadians(mSweepAngle); //将角度转换为弧度
        int cnt = (int) (arcAngle / Math.toRadians(degree));//总的点数
       int  currentPoint= (int) ((mCurrValue*cnt)/mMaxValue);
        canvas.save();
        float startPoint[]=getCoordinatePoint(mRadius-mSparkleWidth*2f,mStartAngle-5);//开始点的坐标
        for (int i = 0; i <= cnt; i++) {
            canvas.rotate(degree, mCenterX, mCenterY);
            if (currentPoint > 0 && currentPoint+1 >= i) {
                canvas.drawPoint(startPoint[0], startPoint[1], currCirPaint);//当前进度
//                canvas.rotate(degree, mCenterX, mCenterY);
                continue;
            }
            canvas.drawPoint(startPoint[0], startPoint[1], cirClePaint);//默认的圆点
        }


    }

    private void drawRunRect(Canvas canvas) {
        arcPaint.setColor(currColor);
        /**
         * 画当前圆弧的进度
         */
        arcPaint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(rectF, mStartAngle, calculateRelativeAngleWithValue(mCurrValue), false, arcPaint);
        /**
         *小圆点的进度
         */
        arcPaint.setStyle(Paint.Style.FILL);
        float[] point = getCoordinatePoint(mRadius - mSparkleWidth / 2f, mStartAngle + calculateRelativeAngleWithValue(mCurrValue));

        canvas.drawCircle(point[0], point[1], mSparkleWidth / 2.5f, arcPaint);
    }

    private float[] getCoordinatePoint(float radius, float angle) {
        float[] point = new float[2];

        double arcAngle = Math.toRadians(angle); //将角度转换为弧度
        if (angle < 90) {
            point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius);
            point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);
        } else if (angle == 90) {
            point[0] = mCenterX;
            point[1] = mCenterY + radius;
        } else if (angle > 90 && angle < 180) {
            arcAngle = Math.PI * (180 - angle) / 180.0;
            point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius);
            point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);
        } else if (angle == 180) {
            point[0] = mCenterX - radius;
            point[1] = mCenterY;
        } else if (angle > 180 && angle < 270) {
            arcAngle = Math.PI * (angle - 180) / 180.0;
            point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius);
            point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);
        } else if (angle == 270) {
            point[0] = mCenterX;
            point[1] = mCenterY - radius;
        } else {
            arcAngle = Math.PI * (360 - angle) / 180.0;
            point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius);
            point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);
        }

        return point;
    }

    /**
     * 相对起始角度计算信用分所对应的角度大小
     */
    public float calculateRelativeAngleWithValue(double value) {
        return (float) (mSweepAngle * value / mMaxValue);
    }

    public void setMaxValue(double max) {
        this.mMaxValue = max;
        postInvalidate();
    }

    public void setValue(double value) {
        if (value<0){
            return;
        }
        if (value>mMaxValue){
           value=mMaxValue;
        }
        this.mCurrValue= value;
        lastValue=value;
        postInvalidate();
    }
    /**
     * 设置信用值并播放动画
     *
     * @param creditValue 信用值
     */
    public void setCreditValueWithAnim(double creditValue) {
        if (!isAnimFinish || creditValue <0) {
            return;
        }
        if (creditValue > mMaxValue) {
            creditValue = mMaxValue;
        }

        lastValue = this.mCurrValue;//记录最后一次的角度,每次从这里开始
        /**
         * 设置动画
         */
        setAnimator((float) lastValue, (float) creditValue);
        lastValue=creditValue;
    }

    /**
     * @param last    最后的角度
     * @param current 当前角度
     */
    private void setAnimator(float last, float current) {
        progressAnimator = ValueAnimator.ofFloat(last, current);
        progressAnimator.setDuration(1000);
        progressAnimator.setTarget(mCurrValue);
        progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrValue = (float) animation.getAnimatedValue();
                postInvalidate();
//                curValues = currentAngle / k;
            }
        });
        progressAnimator.start();
    }

    /**
     * dp--->px
     *
     * @param dp
     * @return
     */
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                Resources.getSystem().getDisplayMetrics());
    }

    /**
     * sp--->px
     *
     * @param sp
     * @return
     */
    private int sp2px(int sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
                Resources.getSystem().getDisplayMetrics());
    }

}
